﻿using System;

namespace MathService
{
    public static class ComplexExtentions
    {
        /* - Массивы ---------------------------------------------------------------------------------- */

        #region Массивы

        /// <summary>Преобразование массива комплексных чисел в масив действительных</summary>
        /// <param name="c">Массив комплексных чисел</param>
        /// <returns>Массив действительных чисел</returns>
        public static double[] ToRe(this Complex[] c)
        {
            var Result = new double[c.Length];

            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++) Result[i] = c[i].Re;

            return Result;
        }

        /// <summary>Массив комплексных чисел в массив значений мнимых чисел</summary>
        /// <param name="c">Массив комплексных чисел</param>
        /// <returns>Массив значений комплексных мнимых чисел</returns>
        public static double[] ToIm(this Complex[] c)
        {
            var Result = new double[c.Length];

            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++) Result[i] = c[i].Im;

            return Result;
        }

        /// <summary>Массив комплексных чисел в массив модулей</summary>
        /// <param name="c">Массив сомплексных чисел</param>
        /// <returns>Массив модулей комплексных чисел</returns>
        public static double[] ToAbs(this Complex[] c)
        {
            var Result = new double[c.Length];

            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++) Result[i] = c[i].Abs;

            return Result;
        }

        /// <summary>Массив сомплексных чисел в массив аргументов</summary>
        /// <param name="c">Массив комплексных чисел</param>
        /// <returns>Массив аргументов комплексных чисел</returns>
        public static double[] ToArg(this Complex[] c)
        {
            var Result = new double[c.Length];

            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++) Result[i] = c[i].Arg;

            return Result;
        }

        /// <summary>
        /// Массив комплексных чисел в двумерный массив действительных и мнимых частей, где
        /// Re = V[i,0]
        /// Im = V[i,1]
        /// </summary>
        /// <param name="c">Массив комплексных чисел</param>
        /// <returns></returns>
        public static double[,] ToReImArray(this Complex[] c)
        {
            var Result = new double[c.Length, 2];
            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++)
            {
                Result[i, 0] = c[i].Re;
                Result[i, 1] = c[i].Im;
            }
            return Result;
        }

        public static double[,] ToAbsArgArray(this Complex[] c)
        {
            var Result = new double[c.Length, 2];
            var i_Length = c.Length;
            for(var i = 0; i < i_Length; i++)
            {
                Result[i, 0] = c[i].Abs;
                Result[i, 1] = c[i].Arg;
            }
            return Result;
        }

        /// <summary>Преобразовать массив действительных в массив комплексных чисел</summary>
        /// <param name="Re">Массив действительных чисел</param>
        /// <returns>Массив комплексных чисел</returns>
        public static Complex[] ToComplex(this double[] Re)
        {
            var Result = new Complex[Re.Length];

            var i_Length = Re.Length;
            for(var i = 0; i < i_Length; i++)
                Result[i] = Re[i];

            return Result;
        }

        /// <summary>Преобразовать двумерный массив действительных в массив комплексных чисел</summary>
        /// <param name="Values">Двумерный массив действительных чисел, где Re = V[i,0], Im = V[i,1]</param>
        /// <returns>Массив комплексных чисел</returns>
        public static Complex[] ToComplex(this double[,] Values)
        {
            if(Values.GetLength(1) != 2)
                throw new ArgumentException("Операция возможна для массива с размерностью [N,2]");
            var N = Values.GetLength(0);
            var Result = new Complex[N];
            for(var i = 0; i < N; i++)
                Result[i] = new Complex(Values[i, 0], Values[i, 1]);
            return Result;
        }

        public static Complex[] GetAbs(this Complex[] c)
        {
            var lv_ComplexArray = new Complex[c.Length];
            var length = c.Length;
            for(var i = 0; i < length; i++)
                lv_ComplexArray[i] = c[i].Abs;
            return lv_ComplexArray;
        }



        #endregion

        /* -------------------------------------------------------------------------------------------- */
    }
}
